package org.yxt.springclod.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.yxt.springcloud.entities.CommonResult;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 使用hystrix保证系统正常运行
 * <p>
 * 模拟业务出错激活hystrix作用，激活hystrix场景有
 * 程序异常 响应超时 服务并发过大 服务处理线程满负荷的情况
 *
 * @author Yang douya
 * @date 2022-01-03
 */
@Service
public class PaymentHystrixService {

    /**
     * 模拟正常响应数据的业务场景
     *
     * @param id
     * @return
     */
    public CommonResult getOk(int id) {
        // 客户端80中使用在openFeign客户端中做对服务端接口全局降级处理
        //int x = 10/0;
        return new CommonResult(1, "线程池：" + Thread.currentThread().getName() + " getOk param id = " + id);
    }

    /**
     * 模拟耗时 出错等响应数据的业务场景
     * HystrixCommand(fallbackMethod = " getFailFallbackHandler ", commandProperties = { name = " execution.isolation.thread.timeoutInMilliseconds ", value = " 3000 " })
     * })
     *
     * @param id
     * @return 解释如果执行的线程处理时间超过3秒的条件，将自动调用降级执行getFailFallbackHandler方法
     */
    @HystrixCommand(fallbackMethod = "getFailFallbackHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public CommonResult getFail(int id) {
        // 手动让处理业务时间大于3秒 进入服务降级
        int sleepTime = 5;
        try {
            TimeUnit.SECONDS.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //int age = 10/0;
        return new CommonResult(1, "线程池：" + Thread.currentThread().getName() + " getFail param id = " + id + " 耗时操作(秒) " + sleepTime);
    }

    /**
     * 服务降级兜底方法
     *
     * @param id
     * @return
     */
    public CommonResult getFailFallbackHandler(int id) {
        return new CommonResult(0, "线程池：" + Thread.currentThread().getName() + " getFailFallbackHandler param id = " + id + " 系统繁忙，服务自动降级处理");
    }

    /**
     * 在10秒内发生10次请求，有60%的失败，将打开断路器
     *
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "circuitBreakerFallbackHandler", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //开启断路器 开启熔断机制
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 请求10此次
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 在10秒内
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //失败率达到多少后跳闸
    })
    public CommonResult circuitBreaker(int id) {
        if (id < 0) {
            throw new RuntimeException("======id 不能为负数========");
        }
        String uuid = UUID.randomUUID().toString();
        return new CommonResult(1, "当前线程 " + Thread.currentThread().getName() + " 未到达Hystrix设置的上线阈值 流水号 " + uuid);
    }

    public CommonResult circuitBreakerFallbackHandler(int id) {
        return new CommonResult(0, "这里是服务降级兜底处理类", "参数 id 不能小于0 id = " + id);
    }
}
